#include <iostream>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <sys/types.h>

using namespace std;
#define MAX 1024
int main()
{
    int pipefd[2] = {0};
    if (pipe(pipefd) == -1)
    {
        perror("pipe");
        return 1;
    }

    int id = fork();
    if (id < 0)
    {
        perror("fork");
        return 1;
    }
    // 子进程写
    if (id == 0)
    {
        close(pipefd[0]);
        int cnt = 10;

        while (true)
        {
            // write(pipefd[1], "a", 1);
            // cnt++;
            // cout << cnt << endl;
            char message[MAX];
            snprintf(message, sizeof(message), "send message cnt: %d to father", cnt);
            write(pipefd[1], message, strlen(message));
            cnt--;
            cout << cnt << endl; // 代表正在写入
            sleep(1);
        }
    }
    close(pipefd[1]);
    char receive[MAX];
    while (true)
    {
        // int n = read(pipefd[0], receive, sizeof(receive) - 1);
        // if (n > 0)
        // {
        //     receive[n] = 0;
        //     cout << receive << endl;
        // }
        // perror("read");
        // cout << "n:" << n << endl;
        sleep(5);
        break; //读端关闭
    }
    close(pipefd[0]);
    sleep(5);
    int status = 0;
    pid_t rid = waitpid(id, &status, 0);
    if(rid == id)
        cout << (status&0x7F) << endl; //注意要加(),因为<<的优先级大于&
    return 0;
}

// a. 管道的4种情况
//    1. 正常情况，如果管道没有数据了，读端必须等待，直到有数据为止(写端写入数据了)
//    2. 正常情况，如果管道被写满了，写端必须等待，直到有空间为止(读端读走数据)
//    3. 写端关闭，读端一直读取, 读端会读到read返回值为0， 表示读到文件结尾
//    4. 读端关闭，写端一直写入，OS会直接杀掉写端进程，通过想目标进程发送SIGPIPE(13)信号，终止目标进程 ---- 如何证明？？
// b. 管道的5种特性
//    1. 匿名管道,可以允许具有血缘关系的进程之间进行进程间通信，常用与父子,仅限于此
//    2. 匿名管道，默认给读写端要提供同步机制 --- 了解现象就行
//    3. 面向字节流的 --- 了解现象就行
//    4. 管道的生命周期是随进程的
//    5. 管道是单向通信的，半双工通信的一种特殊情况
